package io.gitee.tianhaoran.chat.sdk.api;

import io.gitee.tianhaoran.chat.common.exception.ChatException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okio.BufferedSource;

import javax.annotation.Nullable;
import java.nio.charset.StandardCharsets;
import java.util.Optional;

/**
 * <p>
 * 作者：沈自在
 **/
@Slf4j
public abstract class AbstractEventSourceListener extends EventSourceListener {
    @Override
    public void onClosed(@Nullable EventSource eventSource) {
        log.debug("[AI-Chat] Execute onClosed method.");
    }

    @Override
    public void onEvent(@Nullable EventSource eventSource, String id, String type, @Nullable String data) {
        log.debug("[AI-Chat] Execute onEvent method.");
        log.debug("[AI-Chat] id: {}, type: {}, data: {}", id, type, data);
    }

    @Override
    public void onFailure(@Nullable EventSource eventSource, Throwable e, okhttp3.Response response) {
        String errorMsg = Optional.ofNullable(e)
                .map(Throwable::getMessage)
                .orElse(Optional.ofNullable(response)
                        .map(okhttp3.Response::body)
                        .map(ResponseBody::source)
                        .map(bufferedSource -> {
                            try {
                                bufferedSource.request(Long.MAX_VALUE);
                            } catch (Exception ex) {
                                throw new ChatException(ex);
                            }
                            return bufferedSource;
                        })
                        .map(BufferedSource::getBuffer)
                        .map(buffer -> buffer.clone().readString(StandardCharsets.UTF_8))
                        .orElse("Unexpected exception"));
        throw new ChatException(errorMsg);
    }

    @Override
    public void onOpen(@Nullable EventSource eventSource, @Nullable Response response) {
        log.debug("Execute onOpen method, response: {}", response);
    }
}
